namespace SimpleWebServices.Net
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.IO;
    using System.Net.Mime;
    using System.Text;

    public sealed class FormData : IHttpContent
    {
        private NameValueCollection _form;

        public FormData()
        {
            this._form = new NameValueCollection();
        }

        public FormData(IDictionary<string, string> data)
            : this()
        {
            if (null != data)
            {
                foreach (var datum in data)
                {
                    this.Add(datum.Key, datum.Value);
                }
            }
        }

        public ContentType Type
        {
            get
            {
                return new ContentType("application/x-www-form-urlencoded");
            }
        }

        public string this[int index]
        {
            get
            {
                return this._form[index];
            }
        }

        public string this[string name]
        {
            get
            {
                return this._form[name];
            }
        }

        public FormData Add(string name, string value)
        {
            if (null == name)
            {
                throw new ArgumentNullException("name");
            }
            else if (0 == name.Length)
            {
                throw new ArgumentOutOfRangeException("name");
            }

            this._form.Add(name, value);

            return this;
        }

        public void Write(Stream stream)
        {
            if (null == stream)
            {
                throw new ArgumentNullException("stream");
            }

            StringBuilder buffer = new StringBuilder();
            foreach (string key in this._form.Keys)
            {
                if (0 != buffer.Length)
                {
                    buffer.Append('&');
                }

                string value = this._form[key];
                if (null != value)
                {
                    value = value.Replace("=", "%3D").Replace("+", "%2B").Replace(' ', '+').Replace(Environment.NewLine, "%0D%0A");
                }

                buffer.Append(string.Concat(key, "=", value));
            }

            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(buffer.ToString());
            }
        }
    }
}